为什么 C++ 中提倡尽量避免使用宏 #define(转) 您所在的位置:网站首页 define 替换函数 为什么 C++ 中提倡尽量避免使用宏 #define(转)

为什么 C++ 中提倡尽量避免使用宏 #define(转)

2023-12-29 19:13| 来源: 网络整理| 查看: 265

C++ 的书上常说,尽量不要用 #define 来定义常量。这究竟是为什么呢?

其实 C++ 并不仅仅不提倡用宏来定义常量,而且还不提倡用宏来定义“函数”。事实上 C++ 并不是很喜欢预处理宏,在很多很多方面,如果不是必需,尽量不要使用预处理宏。

为什么 C++ 不喜欢预处理宏?

首先,预处理宏是“全局”的。所以,在 C++ 这样如此强调命名空间、类这样的东西的语言中,全局的东西真是越少越好。但是其实预处理宏的全局并不是语义上的全局,之所以叫预处理宏,是因为预处理宏会在编译器编译代码之前被简单地替换成代码。

然后,正因为预处理宏会被简单替换,所以替换的结果是不可预料的。这些说起来还是比较模糊,所以下面将举一些实际的例子。

#define 会把其后的注释也简单地替换

 

#define PI 3.14159 // This is a constant. /* Some harmonious code */ double radius = 2.0; double area = PI * radius * radius ; cout ++y ? ++x : ++y);

所以 n 的值会是 8. 其实这种小错误还算不错了,还有更错的。

#define 定义的函数不“认识” C++ 里的 template

当 #define 出生的时候,还没有 template, 似乎也没有 // 开头的注释。考虑如下代码:  

#define max(a,b) (a > b ? a : b) template class example { /* ... */ public: bool operator>(const example &foo) const { /* ... */ } }; /* ... */ template x, y; /* ... */ template n = max(example(x), example(y));

这里的最后一行的 max 宏会把 example(x) 视为 b. 后面的东西就会报错了。在 C 语言里只考虑到了括号内的逗号,而没考虑大小于号里的括号。

但是为什么 C++ 又没有放弃支持 #define

C 语言里有一个 assert.h , 是必须要用宏来实现的。除此之外,C++ 似乎有一种在运行时获取“类”的名字的思路,就是使用宏。还有,宏可以避免头文件被多次包含。而且有的时候需要一些预定义的宏,来控制代码在不同的环境下的编译。

有的时候,对于一些要重复多次,并且比较长的代码,可以在局部启用宏。但是在用完的地方一定要使用 #undef 将其取消。但是大多时候,尽量不要用宏来定义常数和“函数”。

那在 C++ 中应该怎么办才能替代 #define 的一些功能

C++ 不但能替代一些 #define 没有完善的功能,而且能做得更好。对于常数定义,在 C++ 中使用 const 就可以了。对于一些简单的“函数”,可以使用 C++ 的 inline 修饰符,使用这个修饰符,效果上会和一般的函数一样,但是实际上编译器会把函数中的代码根据语义替换到调用函数的地方,所以运行效率不会受到太大影响。而且在使用 max(++i, ++j) 之类的函数的时候,不会是简单替换,所以 ++i 和 ++j 分别只被计算一次。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有